﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Dynamic;
using Ruandao;

namespace Ruandao.Misc
{
    /// <summary>
    /// 动态匿名类，作用是使用反射的方法从任意类型中获取属性的值。一般用于包装匿名对象，因为当匿名对象作为方法的
    /// 的返回值或作为参数传递时，匿名对象离开了被创建的上下文，因而将被当作是object类型而丢失类型信息，用动态类
    /// 的语法包装反射调用可简化代码的书写。
    /// </summary>
    public class DynamicAnonymous : DynamicObject
    {
        private object baseObject;
        public DynamicAnonymous(object baseObject)
        {
            this.baseObject = baseObject;
        }
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            string name = binder.Name;
            foreach (var p in baseObject.GetType().GetProperties())
            {
                if (p.Name == name)
                {
                    result = baseObject.GetType().GetProperty(name).GetValue(baseObject, null);
                    return true;
                }
            }
            throw new InvalidCodeException("对象的属性'" + binder.Name + "'不存在.");
        }
    }

    public static class AnonymousObjectExtenstion
    {
        /// <summary>
        /// object转DynamicAnonymous
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static dynamic AsDynamic(this object obj)
        {
            return new DynamicAnonymous(obj);
        }
    }
}